Developing Machines For Buzz
To create machines, you need MS Visual C++ 5.0 with the latest service pack installed.
Try building one of the example machines found in the Buzz\Dev folder first to make sure it works.
Before you start to make anything yourself, study the sourcecode for the other machines
and make try to understand it. It's currently the only way to learn to code these machines,
because I'm too lazy to write cool tutorials.
Here are the steps needed to create a machine:
Create the VC project:
- Create new Win32 Dynamic-Link library project
- Set code generation settings to:
- Processor: Pentium
- Use Run-Time Library: Debug Multithreaded DLL (debug) and Multitheaded DLL (release)
- Calling convention: __fastcall
- Struct member alignment: 4 bytes
- Add a new C++ source file to the project and put #include "MachineInterface.h" on the top
Create instances of CMachineParameter:
CMachineParameter const paraCutoff =
{
pt_byte, // type
"Cutoff", // short (one or two words) name
"Cutoff frequency (0-7F)", // longer description
0, // minumum value
127, // maximum value
255, // some value outside [min..max] range
MPF_STATE // flags
};
CMachineParameter const paraNote =
{
pt_note, // type
"Note", // short (one or two words) name
"Note", // longer description
NOTE_MIN, // always same for notes
NOTE_MAX, // "
NOTE_NO, // "
0 // flags
};
Create array of pointers to the parameter descriptors:
CMachineParameter const *pParameters[] =
{
// global parameters first
¶Cutoff,
¶Resonance,
// followed by track parameters
¶Note
};
Create a classes that you use to access the values (not required, but makes it a lot easier):
#pragma pack(1) // <- don't forget that
class gvals
{
public:
byte cutoff; // in the same order as in pParameters
byte resonance;
};
class tvals
{
public:
byte note;
};
#pragma pack()
Create an instance of CMachineInfo:
#define MAX_TRACKS 16
CMachineInfo const MacInfo =
{
MT_GENERATOR, // type, MT_GENERATOR or MT_EFFECT
MI_VERSION, // version, always set this to MI_VERSION
1, // minimum number of tracks
MAX_TRACKS, // maximum number of tracks
2, // number of global parameters
1, // number of track parameters
pParameters, // pointer to list of parameters
0, // number of attributes
NULL, // pointer to list of attributes
#ifdef _DEBUG
"Hoax Generator (debug build)", // name for debug build
#else
"Hoax Generator", // name for release build
#endif
"Hoax", // short name
"Hoax Man", // your name
NULL // list of commands
};
Derive new class from CMachineInterface:
class mi : public CMachineInterface
{
public:
mi();
virtual ~mi(); // must be virtual
virtual void Init(CMachineDataInput * const pi);
virtual void Tick();
virtual bool Work(float *psamples, int numsamples, int const mode);
virtual void SetNumTracks(int const n);
private:
int numTracks;
gvals gval;
tvals tval[MAX_TRACKS];
};
Use DLL_EXPORTS macro to create the necessary export functions:
DLL_EXPORTS
Implement your mi methods:
// intialize pointers to your values in the constuctor
mi::mi()
{
GlobalVals = &gval;
TrackVals = tval;
AttrVals = NULL;
}
mi::~mi()
{
// free any memory you allocated here
}
void mi::Init(CMachineDataInput * const pi)
{
// initialize the machine
// you can ignore pi if you haven't implemented the 'Save' method
}
// this is called by buzz after Init and every time the user adds/deletes a track
void mi::SetNumTracks(int const n)
{
numTracks = n;
}
void mi::Tick()
{
if (gval.cutoff != paraCutoff.NoValue)
{
// gval.cutoff contains new cutoff value
}
if (gval.resonance != paraResonance.NoValue)
{
}
for (int c = 0; c < numTracks; c++)
{
if (tval[c].note == NOTE_OFF)
{
// note off on track c
}
else if (tval[c].note != NOTE_NO)
{
// note on track c
}
}
}
bool mi::Work(float *psamples, int numsamples, int const mode)
{
// generators can ignore the 'mode' argument
// generate 'numsamples' samples to 'psamples' here
// return true if you generated something, false if not
}
BM* Format
This text file explains the inner workings of the BMW and BMX formats.
Midi Recording
This text file explains the inner workings of the MIDI Recording.
Machine Skins
This text file explains the inner workings of the skins.